﻿using TCC.Framework;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.AnimatedValues;
using System;
using System.Reflection;

namespace TCC.Framework
{
    [CustomEditor(typeof(ResetHandler))]
    public class ResetHandlerInspector : Editor
    {
        private PageEditor _sourcePage;
        private SerializedProperty _bgSource;
        private SerializedProperty _otherSource;
        
        private PageEditor _uiPage;
        private SerializedProperty _canvas;
        private SerializedProperty _homePage;
        private List<string> _pages = new List<string>();
        private int SelecteIndex
        {
            get => _pages.IndexOf(_homePage.stringValue);
            set
            {
                if (_pages.IndexOf(_homePage.stringValue) == value) return;
                serializedObject.Update();
                _homePage.stringValue = _pages[value];
                serializedObject.ApplyModifiedProperties();
            }
        }

        private PageEditor _languagePage;
        private SerializedProperty _languageDate;
        private SerializedProperty _defaultLanguagel;

        private PageEditor _objPoolPage;
        private SerializedProperty _objectPool;

        private PageEditor _controllerPage;
        private SerializedProperty _mainCamera;
        private SerializedProperty _moveSpeed;
        private SerializedProperty _rotateSpeed;
        private SerializedProperty _role;
        private SerializedProperty _scrollWheelSpeed;
        private SerializedProperty _initXRotate;
        private SerializedProperty _initYRotate;
        private SerializedProperty _distance;
        private SerializedProperty _minDistance;
        private SerializedProperty _maxDistance;
        private SerializedProperty _yMinAngleLimit;
        private SerializedProperty _yMaxAngleLimit;
        private SerializedProperty _isNeedDamping;
        private SerializedProperty _dampingTime;
        private SerializedProperty _rayHitRoot;
        private SerializedProperty _rayHitText;

        private PageEditor _inputPage;
        private SerializedProperty _inputDeviceType;
        private SerializedProperty _isEnableInputDevice;
        private List<string> _inputDevices = new List<string>();
        private int SelectDevice
        {
            get => _inputDevices.IndexOf(_inputDeviceType.stringValue);
            set
            {
                if (_inputDevices.IndexOf(_inputDeviceType.stringValue) == value) return;
                serializedObject.Update();
                _inputDeviceType.stringValue = _inputDevices[value];
                serializedObject.ApplyModifiedProperties();
            }
        }

        private PageEditor _hotfixPage;
        private SerializedProperty _isHotfix;
        private SerializedProperty _updataHandle;
        private SerializedProperty _resServerUrl;
        private SerializedProperty _downloadRoutinneNum;
        private SerializedProperty _loadMode;

        private Color _initBgColor;
        private Color _initColor;

        private void OnEnable()
        {
            _sourcePage = new PageEditor(new GUIContent("音频"));
            _uiPage = new PageEditor(new GUIContent("UI"));
            _languagePage = new PageEditor(new GUIContent("本地化语言"));
            _objPoolPage = new PageEditor(new GUIContent("对象池"));
            _hotfixPage = new PageEditor(new GUIContent("热更新"));
            _controllerPage = new PageEditor(new GUIContent("控制器"));
            _inputPage = new PageEditor(new GUIContent("输入管理"));

            _bgSource = serializedObject.FindProperty("backgroundSource");
            _otherSource= serializedObject.FindProperty("otherSource");
            _canvas = serializedObject.FindProperty("canvas");
            _homePage = serializedObject.FindProperty("homePage");
            _languageDate = serializedObject.FindProperty("languageDate");
            _defaultLanguagel = serializedObject.FindProperty("defaultLanguagel");
            _objectPool = serializedObject.FindProperty("objectPool");
            _isHotfix = serializedObject.FindProperty("isHotfix");
            _resServerUrl = serializedObject.FindProperty("resServerUrl");
            _downloadRoutinneNum = serializedObject.FindProperty("downloadRoutinneNum");
            _loadMode = serializedObject.FindProperty("loadMode");
            _updataHandle = serializedObject.FindProperty("updataHandle");
            _mainCamera = serializedObject.FindProperty("mainCamera");
            _moveSpeed=serializedObject.FindProperty("moveSpeed");
            _rotateSpeed=serializedObject.FindProperty("rotateSpeed");
            _role=serializedObject.FindProperty("role");
            _scrollWheelSpeed=serializedObject.FindProperty("scrollWheelSpeed");
            _initXRotate=serializedObject.FindProperty("initXRotate");
            _initYRotate=serializedObject.FindProperty("initYRotate");
            _distance=serializedObject.FindProperty("distance");
            _minDistance=serializedObject.FindProperty("minDistance");
            _maxDistance=serializedObject.FindProperty("maxDistance");
            _yMinAngleLimit=serializedObject.FindProperty("yMinAngleLimit");
            _yMaxAngleLimit=serializedObject.FindProperty("yMaxAngleLimit");
            _isNeedDamping=serializedObject.FindProperty("isNeedDamping");
            _dampingTime=serializedObject.FindProperty("dampingTime");
            _rayHitRoot = serializedObject.FindProperty("rayHitRoot");
            _rayHitText = serializedObject.FindProperty("rayHitText");

            _inputDeviceType = serializedObject.FindProperty("inputDeviceType");
            _isEnableInputDevice = serializedObject.FindProperty("isEnableInputDevice");

            _inputDevices.Clear();
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
                foreach (var type in assembly.GetTypes())
                    if (typeof(InputDeviceBase).IsAssignableFrom(type))//判断type是否是其派生类
                        if (type.IsClass && !type.IsAbstract && type.Name != "InputDeviceBase")
                            _inputDevices.Add(type.Name);
            if (string.IsNullOrEmpty(_inputDeviceType.stringValue))
                SelectDevice = 0;

            _pages.Clear();
            _pages.Add("<None>");
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
                foreach (var type in assembly.GetTypes())
                    if (typeof(BasePanel).IsAssignableFrom(type))//判断type是否是其派生类
                        if (type.IsClass && !type.IsAbstract && type.Name != "BasePanel") 
                            _pages.Add(type.Name);
            if (string.IsNullOrEmpty(_homePage.stringValue)) 
                SelecteIndex = 0;
        }

        public override void OnInspectorGUI()
        {
            serializedObject.Update();
            _sourcePage.OnDraw(() =>
            {
                EditorGUILayout.PropertyField(_bgSource, new GUIContent("背景音乐播放器"));
                EditorGUILayout.PropertyField(_otherSource, new GUIContent("音效播放器"));
            });
            _uiPage.OnDraw(() =>
            {
                EditorGUILayout.PropertyField(_canvas, new GUIContent("画布"));
                SelecteIndex = EditorGUILayout.Popup(new GUIContent("首界面"),SelecteIndex, _pages.ToArray());
            });
            _languagePage.OnDraw(() =>
            {
                EditorGUILayout.PropertyField(_languageDate, new GUIContent("语言配置文件"));
                EditorGUILayout.PropertyField(_defaultLanguagel, new GUIContent("默认语言"));
            });
            _objPoolPage.OnDraw(() =>
            {
                EditorGUILayout.PropertyField(_objectPool, new GUIContent("对象池"));
            });

            _controllerPage.OnDraw(() =>
            {
                EditorGUILayout.PropertyField(_mainCamera, new GUIContent("主相机"));
                EditorGUILayout.PropertyField(_moveSpeed, new GUIContent("初始移速"));
                EditorGUILayout.PropertyField(_rotateSpeed, new GUIContent("初始转速"));
                EditorGUILayout.PropertyField(_role, new GUIContent("角色"));
                EditorGUILayout.PropertyField(_scrollWheelSpeed, new GUIContent("缩放系数"));
                EditorGUILayout.PropertyField(_initXRotate, new GUIContent("X轴初始旋转角度"));
                EditorGUILayout.PropertyField(_initYRotate, new GUIContent("Y轴初始旋转角度"));
                EditorGUILayout.PropertyField(_distance, new GUIContent("主相机与角色间距"));
                EditorGUILayout.PropertyField(_minDistance, new GUIContent("主相机与角色最小间距"));
                EditorGUILayout.PropertyField(_maxDistance, new GUIContent("主相机与角色最大间距"));
                EditorGUILayout.PropertyField(_yMinAngleLimit, new GUIContent("主相机Y轴上最小角度"));
                EditorGUILayout.PropertyField(_yMaxAngleLimit, new GUIContent("主相机Y轴上最大角度"));
                EditorGUILayout.PropertyField(_isNeedDamping, new GUIContent("是否使用缓动模式"));
                EditorGUILayout.PropertyField(_dampingTime, new GUIContent("缓动系数"));
                EditorGUILayout.PropertyField(_rayHitRoot, new GUIContent("射线目标提示框节点"));
                EditorGUILayout.PropertyField(_rayHitText, new GUIContent("射线目标提示文本组件"));
                if(EditorApplication.isPlaying)
                {
                    _initBgColor = GUI.backgroundColor;
                    _initColor = GUI.color;
                    GUI.backgroundColor = Color.cyan;
                    GUI.color = Color.white;
                    EditorGUILayout.BeginVertical(EditorStyles.helpBox);

                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.LabelField("运行时数据", EditorStyles.boldLabel);
                    EditorGUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                    GUILayout.Label("当前视点: ", GUILayout.Width(60));
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                    GUILayout.Space(20);
                    GUILayout.Label((target as ResetHandler).ControllerMagr.LookPoint.ToString());
                    GUILayout.FlexibleSpace();
                    if (GUILayout.Button("Copy", EditorStyles.miniButton))
                    {
                        GUIUtility.systemCopyBuffer = (target as ResetHandler).ControllerMagr.LookPoint.ToString("F2");
                    }
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                    GUILayout.Label("当前视角: ", GUILayout.Width(60));
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                    GUILayout.Space(20);
                    GUILayout.Label((target as ResetHandler).ControllerMagr.LookAngle.ToString());
                    GUILayout.FlexibleSpace();
                    if (GUILayout.Button("Copy", EditorStyles.miniButton))
                    {
                        GUIUtility.systemCopyBuffer = (target as ResetHandler).ControllerMagr.LookAngle.ToString("F2");
                    }
                    GUILayout.EndHorizontal();

                    EditorGUILayout.EndVertical();
                    GUI.backgroundColor = _initBgColor;
                    GUI.color = _initColor;
                }
            });

            _inputPage.OnDraw(() =>
            {
                EditorGUILayout.PropertyField(_isEnableInputDevice, new GUIContent("开启输入设备"));
                SelectDevice= EditorGUILayout.Popup(new GUIContent("输入设备类型"), SelectDevice, _inputDevices.ToArray());
            });

            EditorGUILayout.PropertyField(_isHotfix, new GUIContent("开启热更"));
            if(_isHotfix.boolValue)
            {
                Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
                Assembly assembly = null;
                for (int i = 0; i < assemblies.Length; i++)
                {
                    if (assemblies[i].FullName.Equals("HybridCLR"))
                        assembly = assemblies[i];
                }
                if(assembly==null)
                {
                    _isHotfix.boolValue = false;
                    Log.Error("当前环境不满足热更，请先安装HybridCLR！");
                }
                else
                {
                    _hotfixPage.OnDraw(() =>
                    {
                        EditorGUILayout.PropertyField(_updataHandle, new GUIContent("热更入口"));
                        EditorGUILayout.PropertyField(_resServerUrl, new GUIContent("资源服务器地址"));
                        EditorGUILayout.PropertyField(_downloadRoutinneNum, new GUIContent("资源下载器数量"));
                        EditorGUILayout.PropertyField(_loadMode, new GUIContent("加载模式"));
                    });
                }
            }
            serializedObject.ApplyModifiedProperties();
        }
    }

    public class PageEditor
    {
        /// <summary>
        /// 是否展开
        /// </summary>
        public AnimBool m_isSpread;

        /// <summary>
        /// 标题内容
        /// </summary>
        public GUIContent m_uiContent;

        public PageEditor(GUIContent uIContent)
        {
            m_isSpread = new AnimBool(true);
            m_uiContent = uIContent;
        }

        public void OnDraw(TAction drawAction)
        {
            using (new EditorGUILayout.VerticalScope("Box"))
            {
                m_isSpread.target = EditorGUILayout.Foldout(m_isSpread.target, m_uiContent);
                if (EditorGUILayout.BeginFadeGroup(m_isSpread.faded))
                {
                    drawAction?.Invoke();
                    GUI.changed = true;
                }
                EditorGUILayout.EndFadeGroup();
            }
        }
    }
}

